<template>
  <div class="app-container">
    <el-card>
      <!-- 按钮区域 -->
      <div class="btn-container">
        <el-button type="primary" icon="el-icon-plus" @click="handleCreate">
          添加
        </el-button>
      </div>

      <!-- 表格区域 -->
      <el-table :data="list" row-key="id" border :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
        <el-table-column prop="name" label="名称" :show-overflow-tooltip="true" />
        <el-table-column label="级别">
          <template slot-scope="{ row }">
            <el-tag :type="row.level | levelFilter">{{ row.level }}级</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" :width="handleWidth">
          <template slot-scope="{ row }">
            <el-button type="primary" size="mini" @click="handleUpdate(row)">
              编辑
            </el-button>
            <el-button v-if="row.children == [] || !row.children" type="danger" size="mini" @click="handleDelete(row)">
              删除
            </el-button>
            <el-button v-if="groupType === '1'" type="warning" size="mini" @click="handlerAuthority(row)">
              分配权限
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 添加编辑对话框 -->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" :close-on-click-modal="false" @close="resetForm('dataForm')">
      <el-form ref="dataForm" :rules="rules" :model="temp" label-position="right" label-width="80px">
        <el-form-item label="名称" prop="name">
          <el-input v-model.trim="temp.name" />
        </el-form-item>
        <el-form-item label="编码" prop="code">
          <el-input v-model.trim="temp.code" />
        </el-form-item>
        <el-form-item label="父级">
          <el-cascader v-model="selectedKeys" :options="list" :props="parentProps" clearable filterable @change="selectedChange" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model.trim="temp.description" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false"> 取 消 </el-button>
        <el-button type="primary" @click="dialogStatus === 'create' ? createData('dataForm') : updateData('dataForm')">
          确 定
        </el-button>
      </div>
    </el-dialog>

    <!-- 权限分配对话框 -->
    <el-dialog title="权限分配" :visible.sync="dialogAuthorityVisible" :close-on-click-modal="false" @close="resetAuthorityTree">
      <group-authority ref="groupAuthority" :group-id="currentId" />
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogAuthorityVisible = false"> 取 消 </el-button>
        <el-button type="primary" @click="updateAuthority"> 确 定 </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { fetchTree, addObj, getObj, updateObj, delObj } from '@/api/base/group' // 接口
import { isEmpty, addLevel, getTreeDeepArr, isDiffForm } from '@/utils' // 公共方法
import { mapGetters } from 'vuex'
import GroupAuthority from './GroupAuthority' // 权限组件
import { validEncode2 } from '@/utils/validate' // 验证规则

export default {
  name: 'GroupList',
  components: { GroupAuthority },
  props: {
    // 接收父组件参数
    groupType: {
      // 1为角色 2为组织机构
      type: String,
      required: true,
      default: ''
    },
    handleWidth: {
      type: String,
      default: '240'
    }
  },
  data() {
    return {
      list: [], // 列表数据
      temp: {
        // 表单数据
        code: undefined,
        name: undefined,
        parentId: '-1',
        description: undefined,
        groupType: this.groupType
      },
      originalForm: null, // 编辑时表单原始数据
      dialogFormVisible: false, // 控制添加或编辑对话框显示或隐藏
      dialogStatus: '', // 对话框状态
      textMap: {
        // 对话框标题
        update: '编辑',
        create: '添加'
      },
      rules: {
        // 表单规则
        code: [
          { required: true, message: '请输入编码', trigger: 'blur' },
          { validator: validEncode2, trigger: 'blur' }
        ],
        name: [
          { required: true, message: '请输入名称', trigger: 'blur' },
          { min: 1, max: 10, message: '长度不能大于10位', trigger: 'blur' }
        ]
      },
      parentProps: {
        // 父级菜单配置项
        value: 'id',
        label: 'name',
        children: 'children',
        checkStrictly: true
      },
      selectedKeys: [], // 父级菜单选中值
      dialogAuthorityVisible: false, // 控制权限对话框显示或隐藏
      currentId: '-1' // 当前选中行的id，传递给权限子组件获取此id的权限
    }
  },
  computed: {
    ...mapGetters(['userId', 'name'])
  },
  created() {
    // 组件创建完成
    this.getList()
  },
  methods: {
    async getList() {
      // 获取列表数据
      try {
        const data = await fetchTree({ groupType: this.groupType })
        addLevel(data)
        this.list = data
      } catch (error) {
        console.log(error)
      }
    },
    selectedChange(value) {
      // 父级菜单变化时
      if (isEmpty(value)) {
        this.temp.parentId = value[value.length - 1]
      } else {
        this.temp.parentId = '-1'
      }
    },
    handleCreate() {
      // 点击添加按钮
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
    },
    createData(formName) {
      // 添加
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          try {
            this.temp.crtUser = this.userId
            this.temp.crtName = this.name
            const { message } = await addObj(this.temp)
            this.dialogFormVisible = false
            this.$message({
              message: message,
              type: 'success'
            })
            this.getList()
          } catch (error) {
            console.log(error)
          }
        }
      })
    },
    async handleUpdate(row) {
      // 点击编辑按钮
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      const { data } = await getObj(row.id)
      this.temp = {
        id: row.id,
        code: data.code,
        name: data.name,
        parentId: data.parentId,
        description: data.description,
        groupType: this.groupType,
        updUser: this.userId,
        updName: this.name
      }
      this.selectedKeys = getTreeDeepArr(data.parentId, this.list)
      this.originalForm = { ...this.temp }
    },
    updateData(formName) {
      // 更新
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          if (!isDiffForm(this.temp, this.originalForm)) {
            this.$message({
              message: '未修改数据不提交！',
              type: 'error'
            })
            this.dialogFormVisible = false
            return false
          }
          try {
            const { message } = await updateObj(this.temp)
            this.dialogFormVisible = false
            this.$message({
              message: message,
              type: 'success'
            })
            this.getList()
          } catch (error) {
            console.log(error)
          }
        }
      })
    },
    handleDelete(row) {
      // 点击删除按钮
      this.$confirm('此操作将永久删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          try {
            await delObj(row.id)
            this.$message.success('删除成功！')
            this.getList()
          } catch (error) {
            console.log(error)
          }
        })
        .catch(() => {})
    },
    handlerAuthority(row) {
      // 点击分配权限按钮
      this.dialogAuthorityVisible = true
      this.currentId = row.id
      setTimeout(() => {
        // 等待子组件渲染完成后再调用其方法
        this.$refs.groupAuthority.getAuthority()
      }, 10)
    },
    updateAuthority() {
      // 点击分配权限对话框中的确定按钮
      setTimeout(() => {
        // 等待子组件渲染完成后再调用其方法
        this.$refs.groupAuthority.updateAuthority()
        this.dialogAuthorityVisible = false
      }, 10)
    },
    resetForm(formName) {
      // 添加编辑对话框关闭时重置表单数据
      this.selectedKeys = []
      this.originalForm = null
      this.temp = {
        code: undefined,
        name: undefined,
        parentId: '-1',
        description: undefined,
        groupType: this.groupType
      }
      this.$refs[formName].resetFields()
    },
    resetAuthorityTree() {
      // 分配权限对话框关闭时清空tree选中项
      this.$refs.groupAuthority.resetTree()
    }
  }
}
</script>
